package com.momoauth.common.core.filter;

import com.alibaba.fastjson2.JSON;
import com.momoauth.common.core.config.CommonConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Component
@Order(1)
public class TokenFilter implements Filter {

    /**
     * 虽然在网关层已实现Token的验证，但为了防止绕开网关访问接口时产生不知名的异常，
     * 这里使用过滤器验证头部是否携带Token，仅做非空判断，不验证Token的有效性
     */

    private final Logger logger = LoggerFactory.getLogger(TokenFilter.class);

    @Resource
    CommonConfig config;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String token = request.getHeader("Authorization");
        String path = request.getRequestURI();
        // 获取免Token的URL
        if (config.getUrl().contains(path)) {
            // 拦截其他Token为空的情况
            if ((token == null || token.isEmpty())) {
                logger.error("Token无效，非法请求。");
                Map<String, Object> map = new HashMap<>();
                map.put("code", 40000);
                map.put("msg", "Token无效，非法请求。");
                handleCustomException(servletResponse, JSON.toJSONString(map));
                return;
            }
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    /**
     * 自定义错误返回信息
     * @param servletResponse
     * @param errorMsg
     */
    private void handleCustomException(ServletResponse servletResponse, String errorMsg) {
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("application/json;charset=UTF-8");
        try (PrintWriter writer = servletResponse.getWriter()) {
            writer.print(errorMsg);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
